package br.com.gbvbahia.vendas.modelos;

import br.com.gbvbahia.vendas.modelos.enums.StatusPedido;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import javax.persistence.CascadeType;

import javax.persistence.Column;
import javax.persistence.Transient;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.GeneratedValue;

import static javax.persistence.FetchType.LAZY;
import javax.persistence.GenerationType;
import javax.persistence.JoinColumn;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;

@Entity
@Table(name = "pedidos")
@NamedQueries({
    @NamedQuery(name = "Pedido.buscarPedidos",
            query = "Select distinct p From Pedido p left join p.cliente.telefones t "
            + " Where (:telefone2 = 'todos' OR t.telefone     like :telefone) "
            + " AND   (:nome2     = 'todos' OR p.cliente.nome like :nome) "
            + " AND   (:status2   = 'todos' OR p.status       = :status) "
            + " Order by p.id "),
    @NamedQuery(name = "Pedido.contarPedidos",
            query = "Select count(distinct p) From Pedido p left join p.cliente.telefones t "
            + " Where (:telefone2 = 'todos' OR t.telefone     like :telefone) "
            + " AND   (:nome2     = 'todos' OR p.cliente.nome like :nome) "
            + " AND   (:status2   = 'todos' OR p.status       = :status) ")   
})
public class Pedido implements Serializable {

    private static final long serialVersionUID = 1L;
    /**
     *
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    /**
     *
     */
    @NotNull(message = "Data do pedido deve ser informada")
    @Column(name = "data_ped", nullable = false)
    @Temporal(TemporalType.DATE)
    private Date dataPed = new Date();
    /**
     *
     */
    @NotNull(message = "Informe o endereco de entrega")
    @ManyToOne
    @JoinColumn(name = "cd_endereco_entrega", nullable = false)
    private Endereco enderecoEntrega;
    /**
     *
     */
    @NotNull(message = "Informe o telefone de contato para este pedido")
    @ManyToOne
    @JoinColumn(name = "cd_telefone_entrega", nullable = false)
    private Telefone telefoneEntrega;
    /**
     *
     */
    @ManyToOne
    @JoinColumn(name = "cd_cliente", nullable = false)
    @NotNull(message = "O cliente do pedido deve ser informado")
    private Cliente cliente;
    /**
     *
     */
    @Min(value = 0, message = "O desconto deve ser maior ou igual a zero")
    @NotNull(message = "Informe o descon de venda")
    @Column(name = "desconto", nullable = false)
    private Double desconto = 0.0d;
    /**
     *
     */
    @OneToMany(mappedBy = "pedido", fetch = LAZY, cascade = CascadeType.ALL)
    private List<ItensPedido> itens = new ArrayList<ItensPedido>();
    /**
     *
     */
    @NotNull(message = "O status do pedido deve ser informado")
    @Enumerated(EnumType.STRING)
    @Column(name = "status_pedido", nullable = false, length = 45)
    private StatusPedido status;
    /**
     *
     */
    @Transient
    private boolean marcado;

    public Pedido() {
        super();
    }

    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Date getDataPed() {
        return this.dataPed;
    }

    public void setDataPed(Date dataPed) {
        this.dataPed = dataPed;
    }

    public List<ItensPedido> getItens() {
        if (itens == null) {
            itens = new ArrayList<ItensPedido>();
        }
        return itens;
    }

    public void setItens(List<ItensPedido> itens) {
        this.itens = itens;
    }

    public Endereco getEnderecoEntrega() {
        return enderecoEntrega;
    }

    public void setEnderecoEntrega(Endereco enderecoEntrega) {
        this.enderecoEntrega = enderecoEntrega;
    }

    public Cliente getCliente() {
        return cliente;
    }

    public void setCliente(Cliente cliente) {
        this.cliente = cliente;
    }

    public Telefone getTelefoneEntrega() {
        return telefoneEntrega;
    }

    public void setTelefoneEntrega(Telefone telefoneEntrega) {
        this.telefoneEntrega = telefoneEntrega;
    }

    public StatusPedido getStatus() {
        return status;
    }

    public void setStatus(StatusPedido status) {
        this.status = status;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 37 * hash + Objects.hashCode(this.id);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Pedido other = (Pedido) obj;
        if (!Objects.equals(this.id, other.id)) {
            return false;
        }
        return true;
    }

    public Double getDesconto() {
        return desconto;
    }

    public void setDesconto(Double desconto) {
        this.desconto = desconto;
    }

    public boolean isMarcado() {
        return marcado;
    }

    public void setMarcado(boolean marcado) {
        this.marcado = marcado;
    }

    public Double getTotalPedido() {
        Double totalP = 0.0d;
        for (ItensPedido ip : getItens()) {
            totalP += ip.getPreco() * ip.getQtd();
        }
        totalP -= getDesconto();
        return totalP;
    }
}
